define([ 'jquery', 'underscore', 'ckeditor', 'js/TEEEM.AJAX'], function (jquery, underscore, ckeditor, TEEEM_AJAX) {

    /* PRIVATE VARIABLES */
    var profile = {
        name: '',
        image: '',
        password: '',
        description: '',
        username: '',
        id: ''
    };

    /* PRIVATE FUNCTIONS */

    /**
     *
     */
    function defineEvents() {
        $(document).on('click', '[data-change-screen]', function () {
            var screen = $(this).attr('data-change-screen');
            changeScreen(screen);
        });

        $(document).on('click', '#submitPost', function () {
            var content = CKEDITOR.instances.editor.getData();
            $('#editor').html('<p style="color: #aaa">Post Something...</p>');
            postMessage(content, function () {
                getMessages(function () {});
            });
        });

        $(document).on('click', '#editor', function () {
            if (CKEDITOR.instances.editor.getData().indexOf("Post Something...") != -1) {
                CKEDITOR.instances.editor.setData('');
            }
        });

        $(document).on('blur', '#editor', function () {
            if (CKEDITOR.instances.editor.getData() == "") {
                CKEDITOR.instances.editor.setData('<p style="color: #aaa">Post Something...</p>');
            }
        });

        $(document).on('click', '#loginSubmit', function () {
            login(function () {});
        });

        $(document).on('change keyup', '[data-login]', function (e) {
            profile.username = $('[data-login="username"]').val();
            profile.password = $('[data-login="password"]').val();

            if (e.keyCode == 13) {
                login(function () {});
            }

        });

        $(document).on('click', '[data-show-user]', function () {
            var id = $(this).attr('data-show-user');
            showUser(id,function () {});
        });

        $(document).on('change', '[data-profile-field]', function (e) {
            profile.name = $('[data-profile-field="name"]').val();
            profile.email = $('[data-profile-field="email"]').val();
            profile.image = $('[data-profile-field="image"]').val();

            updateProfile(function () {});
        });
    }

    function showUser(id, callback) {

        var options = {
            url: "REST/users/" + id,
            callback: function (data) {
                console.assert(data.length == 1, "Call returned more than one item");
                var user = data[0];
                console.log(profile);

                var temp = _.template($('[data-template="sidebarProfile"]').html());
                var html = temp({
                    name: user.name,
                    description: user.description,
                    image: user.image
                });

                $("#sidebar .content").html(html);

                callback();
            }
        };

        TEEEM_AJAX.call(options);
    }

    function login(callback) {

        var options = {
            url: "REST/authenticate",
            data:{
                username: profile.username,
                password: profile.password
            },
            callback: function (data) {
                console.assert(data.length == 1, "Call returned more than one item");
                profile.id = data[0].id;
                getProfile(function () {
                    getMessages(function () {
                        checkMenu();
                        changeScreen('feed');
                    });
                    callback();
                });
            }
        };

        TEEEM_AJAX.call(options);
    }

    /**
     *
     * @param callback
     */
    function getProfile(callback) {
        var options = {
            url: "REST/users/" + profile.id,
            callback: function (data) {
                console.assert(data.length == 1, "Call returned more than one item");
                profile = data[0];
                console.log(profile);

                var temp = [
                    _.template($('[data-template="messageProfile"]').html()),
                    _.template($('[data-template="sidebarProfile"]').html())
                ];
                var html = [
                    temp[0]({
                        name: profile.name,
                        username: profile.username,
                        description: profile.description,
                        image: profile.image,
                        email: profile.email,
                        password: profile.password
                    }),
                    temp[1]({
                        name: profile.name,
                        description: profile.description,
                        image: profile.image
                    })
                ];

                $("#profile").html(html[0]);
                $("#sidebar .profile").html(html[1]);
                $('#userPost .image').css('background-image', 'url("' + profile.image + '")');
                $('#userPost [data-holo]').attr('data-holo', profile.name);
                $('#userPost [data-holo]').html(profile.name);

                callback();
            }
        };

        TEEEM_AJAX.call(options);
    }

    /**
     *
     */
    function updateProfile (callback) {

        var options = {
            url: "REST/updateProfile",
            data: {
                id:profile.id,
                name:profile.name,
                email:profile.email,
                image:profile.image
            },
            callback: function (data) {

                $('#sidebar .profile [data-holo]').attr('data-holo', profile.name).html(profile.name);
                $('#sidebar .profile .image').css('background-image', 'url("' + profile.image + '")');
                $('#userPost .image').css('background-image', 'url("' + profile.image + '")');
                $('#userPost [data-holo]').attr('data-holo', profile.name);
                $('#userPost [data-holo]').html(profile.name);

                callback();
            }
        };

        TEEEM_AJAX.call(options);
    }

    /**
     * Retrieves messages from server. Doesn't change the screen but repopulates the messages
     * @param callback
     */
    function getMessages(callback) {

        var options = {
            url: "REST/posts",
            callback: function (data) {
                var temp = _.template($('[data-template="message"]').html());
                var html = '';
                for (var a in data) {
                    html += temp({
                        name: data[a].name,
                        content: data[a].content,
                        image: data[a].image,
                        id: data[a].id
                    });
                }

                $("#messages").html(html);
                callback();
            }
        };

        TEEEM_AJAX.call(options);
    }

    /**
     * Posts a message to the server.
     * @param content
     * @param callback
     */
    function postMessage(content, callback) {

        var options = {
            url: "REST/posts/new",
            //type: "POST",
            data: {
                user:profile.id,
                content:mysql_real_escape_string(content),
                date:new Date().toString()
            },
            callback: function (data) {
                callback();
            }
        };

        TEEEM_AJAX.call(options);
    }

    /**
     * Ensures the menu is properly populated
     */
    function checkMenu () {
        $('[data-menu]').hide();

        //If not logged in
        if (profile.id == "") {
            $('[data-menu="login"]').show();
        } else {
            $('[data-menu="profile"]').show();
            $('[data-menu="logout"]').show();
            $('[data-menu="feed"]').show();
        }

        $('[data-menu="settings"]').show();
    }

    /**
     * Helper function to correctly store the html in the SQL database
     * @param str
     * @returns {*}
     */
    function mysql_real_escape_string (str) {
        return str.replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, function (char) {
            switch (char) {
                case "\0":
                    return "\\0";
                case "\x08":
                    return "\\b";
                case "\x09":
                    return "\\t";
                case "\x1a":
                    return "\\z";
                case "\n":
                    return "\\n";
                case "\r":
                    return "\\r";
                case "\"":
                case "'":
                case "\\":
                case "%":
                    return "\\"+char; // prepends a backslash to backslash, percent,
                // and double/single quotes
            }
        });
    }

    /**
     * Allows us to switch screens
     * @param screen
     */
    function changeScreen(screen) {
        $('[data-screen]').hide();
        $('#main').show();
        $('[data-screen="' + screen + '"]').fadeIn(400, function () {
            try {
                CKEDITOR.instances.editor.setReadOnly("");
            } catch (e) {}

            if (screen == "Login") {
                $('[data-login="username"]').focus();
            }
        });

        //Set Screen Title
        screen = screen.charAt(0).toUpperCase() + screen.slice(1);
        $('#header .feed [data-holo]').html(screen).attr('data-holo',screen);

        //clear sidebar info
        $("#sidebar .content").html('');
    }

    /**
     * Initialise the CK Editor. The instance must be visible to initialise
     */
    function initCK() {
        CKEDITOR.disableAutoInline = true;
        CKEDITOR.inline('editor');
        var userPost = CKEDITOR.instances.editor;
        userPost.config.language = 'en';
        userPost.config.uiColor = '#ffffff';
        userPost.config.toolbar = [
            { name: 'basicstyles', items: [ 'Bold', 'Italic', 'Underline'] },
            { name: 'paragraph', items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent'] },
            { name: 'links', items: [ 'Link', 'Unlink' ] },
            { name: 'colors', items: [ 'TextColor', 'Uploadcare'] }
        ];
        //userPost.setReadOnly("");
    }

    /* PUBLIC FUNCTIONS */
    var pub = {};

    /**
     * Initialise our file
     * @param options
     */
    pub.init = function (options) {
        initCK();
        defineEvents();

        //if not logged in
        if (profile.id != "") {
            getProfile(function () {});
            getMessages(function () {
                checkMenu();
                changeScreen('feed');
            });
        } else {
            checkMenu();
            changeScreen('login');
        }

        setInterval(function () {
            getMessages(function () {});
        }, 5000);
    };

    return pub;
});